package com.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @ClassName: NioClient
 * @Description:
 * @Date 2024/04/26 16:59
 * @Author songshaoqiu
 **/
public class NioClient {
    public static void main(String[] args) throws IOException {
        //获取 channel通道
        SocketChannel socketChannel = SocketChannel.open();
        //设置成非阻塞
        socketChannel.configureBlocking(false);
        //获取selector
        Selector selector = Selector.open();
        // 客户端连上服务器
        socketChannel.connect(new InetSocketAddress("localhost",9091));
        //将channel注册到selector上，并监听连接事件
        SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_CONNECT);
        //轮询访问selector
        while (true){
            //这一步是阻塞的，在客户端的角度这个方法只面向一个客户端的channel
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey next = iterator.next();
                //如果连接中
                if (next.isConnectable()){
                    SocketChannel channel = (SocketChannel) next.channel();
                    //如果时正在连接，则完成连接
                    if (channel.isConnectionPending()){
                        //finish这个方法执行 标识连接完成
                        channel.finishConnect();
                        //设置成非阻塞模式
                        channel.configureBlocking(false);
                        //给服务端发送消息
                        channel.write(ByteBuffer.wrap("hello server".getBytes()));
                        //向selector 监听服务端返回的数据
                        channel.register(selector,SelectionKey.OP_READ);
                    }
                }else if (next.isReadable()){
                    SocketChannel socketChannel1 = (SocketChannel) next.channel();
                    ByteBuffer allocate = ByteBuffer.allocate(1024);
                    int read = socketChannel1.read(allocate);
                    if (read!=-1){
                        System.out.println("客户端读取服务端的数据:"+new String(allocate.array(),0,read));

                    }
                }
                iterator.remove();
            }
        }

    }
}
